<!--
 * @Description: 多功能表格
-->
<template>
  <div :class="['_ehl_mul_table', { _ehl_mul_table_fixed: big }]">
    <!-- 工具条 -->
    <div v-if="tool['show']" class="_ehl_mul_line">
      <div
        class="_ehl_mul_btn iconfont iconfangda2"
        v-if="tool['max_min'] && big === false"
        @click="big = true"
        >{{ $t('common.zuidahua') }}
      </div>
      <div
        class="_ehl_mul_btn iconfont iconsuoxiao2"
        v-if="tool['max_min'] && big !== false"
        @click="big = false"
        >{{ $t('common.zuixiaohua') }}
      </div>
      <div
        v-if="tool['del'] && select"
        class="_ehl_mul_btn iconfont iconshanchu"
        @click="$emit('delete', delArr)"
        >{{ $t('common.shanchuhang') }}
      </div>
      <slot v-if="tool['other']">
        <div
          v-if="tool['add']"
          class="_ehl_mul_btn iconfont iconcharu"
          @click="$emit('add')"
          >{{ $t('common.tianjia') }}</div
        >
      </slot>
    </div>
    <!-- 表头 -->
    <div v-if="dataCopy.length > 0" class="_ehl_mul_line">
      <!-- 多选框 -->
      <div class="_ehl_mul_item_header select_box" v-if="select">
        <el-checkbox
          style="margin-right: 5px"
          v-model="allCheck"
          @change="val => selectAll(val, index)"
        />
      </div>
      <div
        class="_ehl_mul_item_header"
        v-for="(item, index) in optionsArray"
        :key="index"
      >
        {{ item.label }}
      </div>
    </div>
    <!-- 数据内容 -->
    <template v-if="dataCopy.length > 0">
      <div
        class="_ehl_mul_line"
        v-for="(dataItem, dataIndex) in dataCopy"
        :key="dataIndex"
      >
        <!-- 多选框 -->
        <div class="_ehl_mul_item select_box" v-if="select">
          <el-checkbox v-model="allCheck" @change="val => selectAdd(val)"> </el-checkbox>
        </div>
        <!-- 数据 -->
        <div
          class="_ehl_mul_item"
          v-for="(optionItem, optionIndex) in optionsArray"
          :key="optionIndex"
        >
          <!-- 单选框 -->
          <div v-if="optionItem.type === 'check'">
            <el-checkbox
              v-model="dataItem[optionItem.key]"
              :disabled="optionItem.disabled"
              @change="
                val => {
                  optionItem.change &&
                    optionItem.change(
                      generateParam({
                        val,
                        dataItem,
                        dataIndex,
                        optionItem,
                        optionIndex,
                      }),
                    )
                }
              "
            >
              {{ dataItem[optionItem.key] ? '是' : '否' }}
            </el-checkbox>
          </div>
          <!-- 操作 -->
          <div
            v-if="optionItem.type === 'operate'"
            v-html="optionItem.format(dataItem[optionItem.key])"
            @click="
              optionItem.click(
                generateParam({
                  value: dataItem[optionItem.key],
                  dataItem,
                  dataIndex,
                  optionItem,
                  optionIndex,
                }),
              )
            "
          ></div>
          <!-- 纯展示/自定义 -->
          <div
            v-if="
              optionItem.type === 'label' &&
              (dataItem[optionItem.key] || optionItem.default)
            "
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :title="dataItem[optionItem.key] || optionItem.default || ''"
          >
            <slot
              :name="optionItem.key"
              :data="
                generateParam({
                  value: dataItem[optionItem.key],
                  dataItem,
                  dataIndex,
                  optionItem,
                  optionIndex,
                })
              "
            >
              {{ dataItem[optionItem.key] || optionItem.default || '' }}
            </slot>
          </div>
          <!-- 普通输入框 -->
          <ehl-input
            :ref="optionItem.key"
            v-if="optionItem.type === 'input'"
            v-model="dataItem[optionItem.key]"
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :clear="optionItem.clear"
            :rows="optionItem.rows"
            :disabled="optionItem.disabled"
            :readonly="optionItem.readonly"
            :password="optionItem.password"
            :max="optionItem.max"
            :limit="optionItem.limit"
            :placeholder="optionItem.placeholder"
            :prefix-icon="optionItem.prefixIcon"
            :suffix-icon="optionItem.suffixIcon"
            :format="optionItem.format"
            @enter="
              val => {
                optionItem.enter &&
                  optionItem.enter(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
            @change="
              val => {
                optionItem.change &&
                  optionItem.change(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
          />
          <!-- 数字输入框 -->
          <ehl-input-number
            :ref="optionItem.key"
            v-if="optionItem.type === 'inputNumber'"
            v-model="dataItem[optionItem.key]"
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :disabled="optionItem.disabled"
            :min="optionItem.min"
            :max="optionItem.max"
            :step="optionItem.step"
            :placeholder="optionItem.placeholder"
            :precision="optionItem.precision"
            @change="
              val => {
                optionItem.change &&
                  optionItem.change(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
          />
          <!-- 时间选择框 -->
          <ehl-date
            :ref="optionItem.key"
            v-if="optionItem.type === 'date'"
            v-model="dataItem[optionItem.key]"
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :disabled="optionItem.disabled"
            :date-type="optionItem.dateType"
            :readonly="optionItem.readonly"
            :show-slot="optionItem.showSlot"
            :clear="optionItem.clear"
            :devide="optionItem.devide"
            :picker-options="optionItem.pickerOptions"
            @date-change="
              val => {
                optionItem.dateChange &&
                  optionItem.dateChange(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
          >
          </ehl-date>
          <!-- 下拉选择框 -->
          <ehl-select
            :ref="optionItem.key"
            v-if="optionItem.type === 'select'"
            v-model="dataItem[optionItem.key]"
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :options="optionItem.options"
            :lazy="optionItem.lazy"
            :clear="optionItem.clear"
            :multiple="optionItem.multiple"
            :disabled="optionItem.disabled"
            :filterable="optionItem.filterable"
            :placeholder="optionItem.placeholder"
            :loadingtext="optionItem.loadingtext"
            :prop="optionItem.prop"
            @init="
              (options, search) => {
                optionItem.init &&
                  optionItem.init(
                    generateParam({
                      options,
                      search,
                      value: dataItem[optionItem.key],
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
            @change="
              val => {
                optionItem.change &&
                  optionItem.change(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
          />
          <!-- 下拉选择树 -->
          <ehl-select-tree
            :ref="optionItem.key"
            v-if="optionItem.type === 'selectTree'"
            v-model="dataItem[optionItem.key]"
            :class="optionItem.class || ''"
            :style="optionItem.style || {}"
            :tree="optionItem.tree"
            :lazy="optionItem.lazy"
            :clear="optionItem.clear"
            :check-strictly="optionItem.checkStrictly"
            :disabled="optionItem.disabled"
            :filterable="optionItem.filterable"
            :show-checkbox="optionItem.showcheckbox"
            :placeholder="optionItem.placeholder"
            :indent="optionItem.indent"
            :expand-on-click-node="optionItem.expandOnClickNode"
            :loadingtext="optionItem.loadingtext"
            :devide="optionItem.devide"
            :prop="optionItem.prop"
            @init="
              (options, search) => {
                optionItem.init &&
                  optionItem.init(
                    generateParam({
                      options,
                      search,
                      value: dataItem[optionItem.key],
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
            @change="
              val => {
                optionItem.change &&
                  optionItem.change(
                    generateParam({
                      value: val,
                      dataItem,
                      dataIndex,
                      optionItem,
                      optionIndex,
                    }),
                  )
              }
            "
          />
        </div> </div
    ></template>
    <div v-else class="nodata_placeholder">{{ placeholder }}</div>
  </div>
</template>
<script>
  export default {
    name: 'ehlMulTable',
    components: {
      ehlInput: () => $import('ehlInput'),
      ehlSelect: () => $import('ehlSelect'),
      ehlSelectTree: () => $import('ehlSelectTree'),
      ehlInputNumber: () => $import('ehlInputNumber'),
    },
    props: {
      data: { type: Array, default: () => {} },
      column: { type: Object, default: () => {} },
      select: { type: Boolean, default: () => false },
      placeholder: { type: String, default: () => '暂无数据' },
      formData: { type: Object, default: () => {} },
      formOptions: { type: Object, default: () => {} },
      otherParam: { type: Object, default: () => {} },
      tool: {
        type: Object,
        default: () => ({
          show: true,
          max_min: true,
          del: true,
          other: true,
          add: true,
        }),
      },
    },
    data() {
      return {
        allCheck: true, //表头多选框的状态
        big: false, //是否最大化
        delArr: [], //多选后需要删除的数组
        dataCopy: this.data || {}, //原始数据的浅拷贝
        optionsArray: [], //用于循环生成表单
        optionsCopy: {}, //原配置的深拷贝副本，用于当作参数传递出去
      }
    },
    watch: {
      column: {
        handler: function (val, old) {
          this.init(val)
        },
        deep: true,
      },
      data: {
        handler: function (val, old) {
          this.dataCopy = val
        },
        deep: true,
      },
    },
    created() {
      this.init(this.column)
    },
    methods: {
      //初始化状态
      init(val) {
        this.optionsArray = this.deepCopy(val || {}, this.optionsCopy)
        this.dataCopy.forEach(i => {
          this.allCheck &&= i.checked
        })
      },
      //生成通用参数
      generateParam(param = {}) {
        return Object.assign(
          {},
          {
            current: {
              ...param,
              tableOptions: this.optionsCopy,
              tableData: this.dataCopy,
            },
          },
          {
            formOptions: this.formOptions,
            formData: this.formData,
          },
          { other: this.otherParam || {} },
        )
      },
      //根据原配置文件生成新的配置数组
      deepCopy(obj, param) {
        Object.keys(obj).forEach(key => {
          obj[key].key = key
        })
        // let arr = []
        Object.values(obj).forEach(i => {
          let tmp = this.deepCopy2(i)
          param[tmp['key']] = tmp
          // arr.push(tmp)
        })
        return Object.values(param)
      },
      //深拷贝原配置文件
      deepCopy2(obj) {
        let tmp = {}
        Object.keys(obj).forEach(key => {
          if (obj[key] === undefined || obj[key] === null) {
            tmp[key] = null
          } else if (Array.isArray(obj[key])) {
            tmp[key] = []
            obj[key].forEach(i => {
              if (typeof i === 'object') {
                tmp[key].push(this.deepCopy2(i))
              } else {
                tmp[key].push(i)
              }
            })
          } else if (typeof obj[key] === 'object') {
            tmp[key] = this.deepCopy2(obj[key])
          } else {
            tmp[key] = obj[key]
          }
        })
        return tmp
      },
      selectAll(val) {
        this.dataCopy.forEach(i => {
          i.checked = val
        })
      },
      selectAdd(val, index) {
        if (val) {
          this.delArr = Array.from(new Set([...this.delArr, index]))
        } else {
          this.delArr = this.delArr.filter(i => {
            return i !== index
          })
        }
      },
    },
  }
</script>
<style lang="less" scoped>
  ._ehl_mul_table_fixed {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 99;
    width: 100%;
    height: 100%;
    max-height: 100% !important;
  }

  ._ehl_mul_table {
    width: 100%;
    overflow: auto;
    background: @cpt_white;
    border-top: 1px solid @cpt_grey;
    border-right: 1px solid @cpt_grey;
    border-bottom: 1px solid @cpt_grey;
    border-left: 1px solid @cpt_grey;
    border-radius: @cpt_border_radius;

    .nodata_placeholder {
      width: 100%;
      height: @cpt_line_height;
      text-align: center;
      // border-right: 1px solid @cpt_grey;
      // border-bottom: 1px solid @cpt_grey;
    }

    ._ehl_mul_line {
      display: flex;
      justify-content: flex-end;
      width: 100%;
      height: calc(@cpt_line_height*1.2);
      // border-right: 1px solid @cpt_grey;
      // border-bottom: 1px solid @cpt_grey;

      // div:last-child {
      //   border-right: none;
      // }

      .select_box {
        flex-grow: 0 !important;
        flex-shrink: 0;
        width: 70px !important;
      }

      ._ehl_mul_btn {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100%;
        margin-right: 10px;
        font-size: @cpt_font_size_middle;
        cursor: pointer;

        &::before {
          margin-right: 5px;
        }
      }

      ._ehl_mul_item_common {
        display: flex;
        flex-grow: 1;
        align-items: center;
        justify-content: center;
        width: 1px;
        height: 100%;
        // border-right: 1px solid @cpt_grey;
      }

      ._ehl_mul_item_header {
        ._ehl_mul_item_common();

        font-size: @cpt_font_size_middle;
        font-weight: bold;
        background: @cpt_grey_light;
        // border-top: 1px solid @cpt_grey;
      }

      ._ehl_mul_item {
        ._ehl_mul_item_common();

        padding: 0 5px;
        font-size: @cpt_font_size;

        ._ehl_mul_item_label {
          overflow: hidden;
          text-overflow: ellipsis;
          white-space: nowrap;
        }
      }
    }
  }
</style>
